package com.ruoyi.framework.shiro.web.filter;

import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.shiro.web.filter.authc.UserFilter;
import org.springframework.http.HttpStatus;
import com.alibaba.fastjson.JSON;
import com.ruoyi.common.core.domain.AjaxResult;
import com.ruoyi.common.utils.ServletUtils;

/**
 * 自定义用户过滤器
 * 对于未认证的请求，返回JSON错误响应而不是重定向到登录页面
 * 
 * @author ruoyi
 */
public class CustomUserFilter extends UserFilter
{
    /**
     * 在访问被拒绝时的处理
     * 对于Ajax请求和API请求，返回401 JSON响应
     * 对于普通页面请求，重定向到登录页面
     */
    @Override
    protected boolean onAccessDenied(ServletRequest request, ServletResponse response) throws Exception
    {
        HttpServletRequest httpRequest = (HttpServletRequest) request;
        HttpServletResponse httpResponse = (HttpServletResponse) response;
        
        // 判断是否为Ajax请求或API请求
        if (isAjaxRequest(httpRequest))
        {
            // 返回JSON错误响应
            httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpResponse.setContentType("application/json");
            httpResponse.setCharacterEncoding("utf-8");
            
            AjaxResult ajaxResult = AjaxResult.error("请先登录");
            ServletUtils.renderString(httpResponse, JSON.toJSONString(ajaxResult));
            return false;
        }
        else
        {
            // 返回JSON错误响应
            httpResponse.setStatus(HttpStatus.UNAUTHORIZED.value());
            httpResponse.setContentType("application/json");
            httpResponse.setCharacterEncoding("utf-8");

            AjaxResult ajaxResult = AjaxResult.error("请先登录");
            ServletUtils.renderString(httpResponse, JSON.toJSONString(ajaxResult));
            return false;
        }
    }
    
    /**
     * 判断是否为Ajax请求
     */
    private boolean isAjaxRequest(HttpServletRequest request)
    {
        String requestedWith = request.getHeader("X-Requested-With");
        String accept = request.getHeader("Accept");
        String contentType = request.getHeader("Content-Type");
        
        // 判断是否为Ajax请求
        if ("XMLHttpRequest".equals(requestedWith))
        {
            return true;
        }
        
        // 判断Accept头是否包含application/json
        if (accept != null && accept.contains("application/json"))
        {
            return true;
        }
        
        // 判断Content-Type是否为application/json
        if (contentType != null && contentType.contains("application/json"))
        {
            return true;
        }
        
        // 判断请求路径是否为API路径
        String requestURI = request.getRequestURI();
        if (requestURI != null && (requestURI.startsWith("/api/") || requestURI.contains("/ajax/")))
        {
            return true;
        }
        
        return false;
    }
}